#pragma once
#include "cgzITask.h"
#include <cpprest/http_listener.h>
#include <cpprest/uri.h>
#include <cpprest/json.h>
#include <cpprest/uri_builder.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <msgpack.hpp>

class cgzCHttpS;

using namespace web;
using namespace web::http;
using namespace web::http::experimental::listener;

enum EHTTP_S
{
    HTTPS_LOOP,
    HTTPS_LISTEN,
    HTTPS_CORS,
    HTTPS_RGET,
    HTTPS_RPOST,
    HTTPS_RPUT,
    HTTPS_RDEL,
    HTTPS_RHEAD,
    HTTPS_ROPTS,
};

class cgzCHttpLoopS : public cgzIData
{
public:
    friend class cgzCHttpS;
    cgzCHttpLoopS();
    virtual ~cgzCHttpLoopS();

public:
    EHTTP_S m_cmd;
};

class cgzCHttpListenS : public cgzCHttpLoopS
{
public:
    friend class cgzCHttpS;
    cgzCHttpListenS(bool success);
    virtual ~cgzCHttpListenS();

public:
    bool m_success;
};

class cgzCHttpCorsS : public cgzCHttpLoopS
{
public:
    friend class cgzCHttpS;
    cgzCHttpCorsS();
    virtual ~cgzCHttpCorsS();

public:
    std::map<std::string, std::string> m_cors;
};

class cgzCHttpRecvS : public cgzCHttpLoopS
{
public:
    friend class cgzCHttpS;
    cgzCHttpRecvS(http_request &request, std::string &uri, json::value &params);
    virtual ~cgzCHttpRecvS();

public:
    http_request m_request;
    std::string m_uri;
    json::value m_params;
    std::string m_retstr;
};

class cgzCHttpRGetS : public cgzCHttpRecvS
{
public:
    friend class cgzCHttpS;
    cgzCHttpRGetS(http_request &request, std::string &uri, json::value &params);
    virtual ~cgzCHttpRGetS();
};

class cgzCHttpRPostS : public cgzCHttpRecvS
{
public:
    friend class cgzCHttpS;
    cgzCHttpRPostS(http_request &request, std::string &uri, json::value &params);
    virtual ~cgzCHttpRPostS();
};

class cgzCHttpRPutS : public cgzCHttpRecvS
{
public:
    friend class cgzCHttpS;
    cgzCHttpRPutS(http_request &request, std::string &uri, json::value &params);
    virtual ~cgzCHttpRPutS();
};

class cgzCHttpRDelS : public cgzCHttpRecvS
{
public:
    friend class cgzCHttpS;
    cgzCHttpRDelS(http_request &request, std::string &uri, json::value &params);
    virtual ~cgzCHttpRDelS();
};

class cgzCHttpRHeadS : public cgzCHttpRecvS
{
public:
    friend class cgzCHttpS;
    cgzCHttpRHeadS(http_request &request, std::string &uri, json::value &params);
    virtual ~cgzCHttpRHeadS();
};

class cgzCHttpROptsS : public cgzCHttpRecvS
{
public:
    friend class cgzCHttpS;
    cgzCHttpROptsS(http_request &request, std::string &uri, json::value &params);
    virtual ~cgzCHttpROptsS();
};

class cgzCHttpS : public cgzITask
{
public:
    cgzCHttpS(cgzCThreadPool *pool, const char *name, const char *url, int cid);
    virtual ~cgzCHttpS();

public:
    bool run(int64_t nms) override;
    bool casBusy() override;
    bool todoret(cgzCHttpLoopS *cgzTask);
private:
    void get(http_request request);
    void post(http_request request);
    void put(http_request request);
    void del(http_request request);
    void head(http_request request);
    void options(http_request request);
    void revice(http_request &request, EHTTP_S cmd);
    void decode(http_request &request, web::json::value &params);
protected:
    http_listener *m_pListener;
    std::map<std::string, std::string> m_cors;
    int m_cid;
};

json::value msgpack2json(const msgpack::v1::object &obj,cgzITask* that);